﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.IO.Ports;
using System.Linq;
using System.Runtime.Remoting.Contexts;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;
using Modbus.Device;
using thinger.CommonControlLib;
using WindowsFormsApp1;
using WindowsFormsApp1.Models;
using WindowsFormsApp1.Respostories;

namespace wenshidu
{
    public partial class MonitorFrom : Form
    {
        private SerialPort serialPort = null;
        private ModbusSerialMaster master = null;
        THRecord NewRecord = null;//新增记录
        private int signal = 0; //标识仓库名
        int timeSignal = 0; //标识时间

        public MonitorFrom()
        {
            InitializeComponent();
        }

        //重载构建函数
        public MonitorFrom(int Signal) : this()
        {
            this.signal = Signal;

        }



        /// <summary>
        /// 窗体加载事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_Load(object sender, EventArgs e)
        {
            //加载相关配置
            #region 加载图表配置
            chart1.ChartAreas["ChartArea1"].AxisX.ScaleView.Size = 10;//x坐标显示的个数-----控制这个数量的大小进行缩放     
            chart1.ChartAreas[0].AxisX.LabelStyle.IntervalType = DateTimeIntervalType.Seconds;//设置x轴间隔值单位：秒
            chart1.ChartAreas[0].AxisX.LabelStyle.Interval = 1;//设置X轴的值的间隔大小
            chart1.ChartAreas[0].AxisX.LabelStyle.IsEndLabelVisible = false;//是否在轴末尾显示标记
            chart1.ChartAreas[0].AxisX.LabelStyle.Format = "HH:mm:ss";//设置X轴的数据样式
            chart1.ChartAreas[0].AxisX.ScaleView.MinSizeType = DateTimeIntervalType.Seconds;//设置X轴最小显示单位
            chart1.ChartAreas[0].AxisX.ScaleView.SizeType = DateTimeIntervalType.Seconds; //度量单位
            chart1.ChartAreas[0].AxisX.ScaleView.SmallScrollMinSize = 1;//设置X轴最小显示单位
            chart1.ChartAreas[0].AxisX.ScaleView.SmallScrollMinSizeType = DateTimeIntervalType.Seconds;//设置X轴最小显示单位
            chart1.ChartAreas[0].AxisX.IntervalType = DateTimeIntervalType.Seconds;//设置X轴间隔值单位：秒

            chart1.ChartAreas[0].AxisX.Enabled = AxisEnabled.True;//将X轴始终展示
            chart1.ChartAreas[0].AxisY.Enabled = AxisEnabled.True;//将Y轴始终展示
            chart1.ChartAreas[0].AxisX.MajorGrid.LineColor = Color.Gray;//设置X轴网格线颜色
            chart1.ChartAreas[0].AxisY.MajorGrid.LineColor = Color.Gray;//设置Y轴网格线颜色
            chart1.ChartAreas[0].AxisX.ScrollBar.Enabled = true;//关闭系统的滚动条，也可以不关闭，就可以滑动
            chart1.ChartAreas[0].AxisY.ScrollBar.Enabled = true;//关闭系统的滚动条，也可以不关闭，就可以滑动
            chart1.Series[0].BorderWidth = 2;//线宽
            chart1.Series[1].BorderWidth = 2;//线宽


            #endregion




            //加载X号仓库的数据
            this.dgvData.AutoGenerateColumns = false;//关闭自动生成列
            this.dgvData.DataSource = THRecordsRespostry.GetTHRecords(this.signal);
            
            //加载串口相关配置
            //波特率
            string[] rates = Enum.GetNames(typeof(BaudRateEnum));
            this.cbRate.DataSource = rates;
            //校验位
            string[] parities = Enum.GetNames(typeof(Parity));
            this.cbParity.DataSource = parities;
            //数据位
            string[] dataBits = Enum.GetNames(typeof(DataBitEnum));
            cbDateBit.DataSource = dataBits;
            cbDateBit.SelectedIndex = 1;
            //停止位
            string[] StopBits = Enum.GetNames(typeof(StopBitEnum));
            this.cbStopBit.DataSource = StopBits;
        }

        /// <summary>
        /// 定时器timer1_Tick
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void timer1_Tick(object sender, EventArgs e)
        {
            //Random random = new Random();
            ////chart1.Series[0].Points.AddXY(DateTime.Now, random.Next(50, 110));
            //// 刷新数据
            //double temperature = double.Parse(lblTemperature.Text);
            //chart1.Series[0].Points.AddXY(DateTime.Now, lblTemperature.Text);
            //if (chart1.ChartAreas[0].AxisX.ScaleView.Size > 0)
            //{
            //    // 功能, 使X轴的显示范围在最后一刻
            //    chart1.ChartAreas[0].AxisX.ScaleView.Scroll(System.Windows.Forms.DataVisualization.Charting.ScrollType.Last);
            //}

        }



        /// <summary>
        /// 定时器tmrMain_Tick
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tmrMain_Tick(object sender, EventArgs e)
        {
            // 检查是否连接
            if (this.serialPort == null || !this.serialPort.IsOpen)
            {
                this.tmrMain.Enabled = false;
                return;
            }

            byte slaveId = byte.Parse(txtSlaveId.Text.Trim());//从机地址
            // 如果已连接，请求湿度与湿度
            try
            {
                ushort[] res = this.master.ReadHoldingRegisters(slaveId, 0, 2);//解释 Modbus协议
                // 解析数据
                float temperature = (float)Math.Round(res[0] * 0.1f, 1);
                float humidity = (float)Math.Round(res[1] * 0.1f, 1);

                //生成0.7-1.3之间的随机数
                Random random = new Random();
                double f1 = random.NextDouble() * 0.6 + 0.7;//0.7-1.3之间的随机数
                double f2 = random.NextDouble() * 0.6 + 0.7;
                //将随机数乘以湿度,手动添加噪声
                temperature=(float)Math.Round(temperature*f1,2);
                humidity = (float)Math.Round(humidity * f2, 2);
                //添加数据到图表
                chart1.Series[0].Points.AddXY(DateTime.Now, temperature);
                chart1.Series[1].Points.AddXY(DateTime.Now, humidity);

                
                ////每5秒添加一条记录到数据库
                //timeSignal++;
                //if (timeSignal % 5 == 0)//每5秒添加一条记录到数据库
                //{
                //    NewRecord = new THRecord();
                //    NewRecord.SlaveId = this.signal;
                //    NewRecord.Temperature = temperature;
                //    NewRecord.Humidity = humidity;
                //    NewRecord.Creation = DateTime.Now;
                //    //THRecordsRespostry.AddTHRecord(this.signal, resRecord);
                //    //添加记录到数据库
                //    THRecordsRespostry.AddTHRecord(NewRecord);
                //    //刷新数据
                //    this.dgvData.DataSource = THRecordsRespostry.GetTHRecords(this.signal);
                //    timeSignal = 0;//归零
                //    NewRecord = null;
                //}
                                       
                

                if (chart1.ChartAreas[0].AxisX.ScaleView.Size > 0)
                {
                    // 功能, 使X轴的显示范围在最后一刻
                    chart1.ChartAreas[0].AxisX.ScaleView.Scroll(System.Windows.Forms.DataVisualization.Charting.ScrollType.Last);
                }

                //将湿度改为int类型
                thingerGauge1.CurrentValue = (int)humidity;
                thingerWave1.Value = (int)humidity;

                lblTemperature.Text = temperature.ToString() + "℃";
                lblHumidity.Text = humidity.ToString() + "%";

                //检查是否自动控制
                if (this.chkAutoControl.Checked)
                {
                    // 温度大于xxx,打开加热
                    if (temperature > (float)this.nudTemperatureMax.Value)
                    {
                        this.toggleHot.Checked = false;
                        picHot.Image = global::WindowsFormsApp1.Properties.Resources.off;
                        UpdateHotCoil();
                    }
                    // 温度次小于xxx,关闭加热
                    else if (temperature < (float)this.nudTemperatureMin.Value)
                    {
                        this.toggleHot.Checked = true;
                        picHot.Image = global::WindowsFormsApp1.Properties.Resources.on;
                        UpdateHotCoil();
                    }
                    // 温度大于xxx,打开报警
                    if (temperature > (float)nudTemperatureWarn.Value)
                    {
                        this.picWarn.IsWarning = true;
                    }
                    else
                    {
                        this.picWarn.IsWarning = false;
                    }
                    //湿度大于xxx时，报警
                    if (humidity > (float)this.nudHumidityWarn.Value)
                    {
                        this.picWarn.IsWarning = true;
                    }
                    //湿度大于xxx时，打开风扇
                    if (humidity > (float)this.nudHumidityMax.Value)
                    {
                        this.toggleWater.Checked = true;
                        UpdateWaterCoil();
                        tbpFan.IsRun = true;
                    }
                    //湿度小于xxx时，关闭风扇
                    if (humidity < (float)this.nudHumidityMin.Value)
                    {
                        this.toggleWater.Checked = false;
                        UpdateWaterCoil();
                        tbpFan.IsRun = false;
                    }
                }

            }
            catch (Exception ex)
            {
                this.tmrMain.Enabled = false;
                MessageBox.Show("读取温湿度失败:" + ex.Message);
            }
        }

        /// <summary>
        /// 点击连接
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void thingerToggleAdvance1_Click(object sender, EventArgs e)
        {
            // 是连接还是关闭
            // 如果 checked 为 true, 说明打开 ，否则代表关闭
            if (this.thingerToggleAdvance1.Checked)
            {
                // 检查是否已经打开连接
                if (this.serialPort != null && this.serialPort.IsOpen)
                {
                    return;
                }
                string portName = this.cbPortName.Text.Trim();
                int baudRate = (int)Enum.Parse(typeof(BaudRateEnum), this.cbRate.SelectedItem.ToString());
                //参数解释, 
                this.serialPort = new SerialPort(portName, baudRate);

                try
                {
                    this.serialPort.ReadTimeout = 2000;
                    this.serialPort.WriteTimeout = 2000;
                    this.serialPort.Open();
                    this.master = ModbusSerialMaster.CreateRtu(this.serialPort);//创建ModbusRtuMaster
                    this.lblState.Text = "已连接";
                    this.tmrMain.Enabled = true;
                    //打开定时器
                    this.timer1.Enabled = true;
                }
                catch (Exception ex)
                {
                    MessageBox.Show("连接串口失败:" + ex.Message);
                    this.thingerToggleAdvance1.Checked = false;
                    this.tmrMain.Enabled = false;
                }
            }
            else
            {
                // 关闭
                // 检查是否已经断开
                if (null == this.serialPort || !this.serialPort.IsOpen)
                {
                    return;
                }
                try
                {
                    this.serialPort.Close();
                    this.master = null;
                    this.serialPort = null;
                    this.lblState.Text = "未连接";
                    this.tmrMain.Enabled = false;
                    //关闭定时器
                    this.timer1.Enabled = false;
                }
                catch (Exception ex)
                {
                    MessageBox.Show("断开连接失败:" + ex.Message);
                    this.thingerToggleAdvance1.Checked = true;
                }
            }
        }

        /// <summary>
        /// 加热开关
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void toggleHot_Click(object sender, EventArgs e)
        {
            if (null == this.serialPort || !this.serialPort.IsOpen)
            {
                this.toggleHot.Checked = !this.toggleHot.Checked;
                MessageBox.Show("请连接设备");
                return;
            }

            byte slaveId = byte.Parse(this.txtSlaveId.Text.Trim());

            if (this.toggleHot.Checked)
            {
                // 打开加热设备 0-1

                try
                {
                    // 修改第1个线圈
                    this.master.WriteSingleCoil(slaveId, 0, true);
                    this.picHot.Image = global::WindowsFormsApp1.Properties.Resources.on;
                }
                catch (Exception ex)
                {
                    this.toggleHot.Checked = false;
                    MessageBox.Show("打开加热设备失败:" + ex.Message);
                }

            }
            else
            {
                // 关闭加热设备 1-0
                try
                {
                    // 修改第1个线圈
                    this.master.WriteSingleCoil(slaveId, 0, false);
                    this.picHot.Image = global::WindowsFormsApp1.Properties.Resources.off;
                }
                catch (Exception ex)
                {
                    this.toggleHot.Checked = true;
                    MessageBox.Show("关闭加热设备失败:" + ex.Message);
                }

            }
        }

        /// <summary>
        /// 风扇开关
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void toggleWater_Click(object sender, EventArgs e)
        {
            if (null == this.serialPort || !this.serialPort.IsOpen)
            {
                this.toggleWater.Checked = !this.toggleWater.Checked;
                MessageBox.Show("请连接设备");
                return;
            }
            byte slaveId = byte.Parse(this.txtSlaveId.Text.Trim());
            if (this.toggleWater.Checked)
            {
                try
                {
                    // 修改第1个线圈
                    this.master.WriteSingleCoil(slaveId, 1, true);
                    this.tbpFan.IsRun = true;
                }
                catch (Exception ex)
                {
                    this.toggleWater.Checked = false;
                    MessageBox.Show("打开风扇设备失败:" + ex.Message);
                }
            }
            else
            {
                // 关闭风扇设备 1-0
                try
                {
                    // 修改第1个线圈
                    this.master.WriteSingleCoil(slaveId, 1, false);
                    this.tbpFan.IsRun = false;
                }
                catch (Exception ex)
                {
                    this.toggleWater.Checked = true;
                    MessageBox.Show("关闭风扇设备失败:" + ex.Message);
                }

            }


        }

        /// <summary>
        /// 自动控制状态,更新加热设备状态
        /// </summary>
        private void UpdateHotCoil()
        {
            byte slaveId = byte.Parse(this.txtSlaveId.Text.Trim());
            try
            {
                this.master.WriteSingleCoil(slaveId, 0, this.toggleHot.Checked);
            }
            catch (Exception ex)
            {
                string message = this.toggleHot.Checked ? "打开" : "关闭";
                this.toggleHot.Checked = this.toggleHot.Checked;
                MessageBox.Show($"{message}失败:" + ex.Message);
            }
        }

        /// <summary>
        /// 自动控制状态,更新风扇设备状态
        /// </summary>
        private void UpdateWaterCoil()
        {
            byte slaveId = byte.Parse(this.txtSlaveId.Text.Trim());

            try
            {
                // 修改第1个线圈
                this.master.WriteSingleCoil(slaveId, 1, this.toggleWater.Checked);
                //this.master.WriteSingleCoil(2, 0, this.toggleWater.Checked);
            }
            catch (Exception ex)
            {
                string message = this.toggleWater.Checked ? "打开" : "关闭";
                this.toggleHot.Checked = this.toggleWater.Checked;
                MessageBox.Show($"{message}失败:" + ex.Message);
            }
        }

        private void label6_Click(object sender, EventArgs e)
        {
            
        }

        private void bt_SavePro_Click(object sender, EventArgs e)
        {
            //系统响铃提示一下
            System.Media.SystemSounds.Asterisk.Play();


            //读取状态写入到相对目录ExportData文件夹下Profiles.txt文件,
            //string directoryPath = @"..\\..\\ ExportData";
            //if (!Directory.Exists(directoryPath))
            //{
            //    Directory.CreateDirectory(directoryPath);
            //}

            string path = @"..\\..\\ ExportData\\Profiles.txt";

            string content = "";//要写入的内容
            content += this.txtSlaveId.Text.Trim() + ",";//从机地址
            content += this.cbPortName.Text.Trim() + ",";//串口号
            content += this.cbRate.SelectedItem.ToString() + ",";//波特率
            content += this.cbParity.SelectedItem.ToString() + ",";//校验位
            content += this.cbDateBit.SelectedItem.ToString() + " \n";//数据位


            //使用StreamWriter类写入文件
            using (StreamWriter sw = new StreamWriter(path))
            {
                //清除缓存区
                sw.BaseStream.Seek(0, SeekOrigin.End);//将文件指针移到文件尾
                //sw.BaseStream.SetLength(0);//清除文件内容
                //写入文件头部信息
                sw.WriteLine("从机地址,串口号,波特率,校验位,数据位");

                //追加写入
                //sw.WriteLine();
                
                sw.WriteLine(content);
            }
        }

      


    }
}
